#include "categoryview.h"
#include <iostream>

CategoryView::CategoryView():editstatus(false),mydoc(0),menuCategoryMoveMode("Category Move Mode")
{
	//Create the Tree model:
	refTreeModel = Gtk::TreeStore::create(columns);
	set_model(refTreeModel);
	//Add the TreeView's view columns:
	categorycolumn.set_title("Category");
	categorycolumn.pack_start(cellrenderer);
	categorycolumn.set_resizable(true);
	append_column(categorycolumn);	
	append_column("Count",columns.count);
	set_headers_visible(false);
	categorycolumn.set_cell_data_func(cellrenderer, sigc::mem_fun(*this, &CategoryView::datarender) );
	cellrenderer.signal_edited().connect(sigc::mem_fun(*this, &CategoryView::save_category) );
	//激活拖拽功能
	//signal_drag_end().connect( sigc::mem_fun(*this, &CategoryView::drag_end) );
	signal_drag_data_received().connect(sigc::mem_fun(*this,&CategoryView::drag_data_received) );
	c1=signal_drag_data_get().connect(sigc::mem_fun(*this,&CategoryView::drag_data_get));
	signal_row_activated().connect(sigc::mem_fun(*this,&CategoryView::select_category));
	//TEST MULTI DRAG HERE
	std::vector<Gtk::TargetEntry> targets;
	targets.push_back( Gtk::TargetEntry("CATEGORY-ID") );
	//targets.push_back( Gtk::TargetEntry("GTK_TREE_MODEL_ROW") );
	drag_source_set(targets);
	enable_model_drag_source(targets);
	//enable_model_drag_source(targets,Gdk::MODIFIER_MASK,Gdk::ACTION_COPY|Gdk::ACTION_MOVE);
	targets.push_back( Gtk::TargetEntry("DOCUMENT-ID") );
	drag_dest_set(targets);
	//enable_model_drag_dest(targets);
	//应该不允许拷贝模式，只允许移动模式
	enable_model_drag_dest(targets,Gdk::ACTION_MOVE); 
	
	//Fill popup menu:
	{
    Gtk::Menu::MenuList& menulist = menuPopup.items();

    menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Insert",sigc::mem_fun(*this, &CategoryView::insert_category) ) );
    menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Edit", sigc::mem_fun(*this, &CategoryView::edit_category) ) );
    menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Remove",sigc::mem_fun(*this, &CategoryView::remove_category) ) );
	menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Remove All",sigc::mem_fun(*this, &CategoryView::remove_all_category) ) );
		menulist.push_back( Gtk::Menu_Helpers::SeparatorElem() );
		menuCategoryMoveMode.signal_activate().connect(sigc::mem_fun(*this, &CategoryView::category_movemode) );
		//menulist.push_back(Gtk::Menu_Helpers::CheckMenuElem("_Category Move Mode",sigc::mem_fun(*this, &CategoryView::category_movemode) ) );

  }
	menuPopup.append(menuCategoryMoveMode);

 	menuPopup.accelerate(*this); 
	menuPopup.show_all();
}

CategoryView::~CategoryView()
{
}

void CategoryView::set_documents(sdms::documents* doc)
{
	mydoc=doc;
}

//处理树状模型时，遍历只能在子级别上
//若需更深层次的级别，或无限制的级别，则需要使用递归方式
//若只有二级分类，则直接遍历效果更好
void CategoryView::getrow(Gtk::TreeModel::Children child,std::string pname, Gtk::TreeModel::Row& row)
{

}

void CategoryView::update()
{
	if (!mydoc) return;
	std::vector<sdms::category> t=mydoc->getcategory();
	refTreeModel->clear();
	for(int i=0;i<t.size();i++)
	{
        Gtk::TreeModel::Row row;
		row= *(refTreeModel->append());
		if (row) {
			row[columns.name] =  t[i].name;
			row[columns.count]=t[i].count;		
		}
		expand_all();
	}
}

bool CategoryView::on_button_press_event(GdkEventButton* event)
{
  //Call base class, to allow normal handling,
  //such as allowing the row to be selected by the right-click:
  bool return_value = TreeView::on_button_press_event(event);

  //Then do our custom stuff:
  if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
  {
    menuPopup.popup(event->button, event->time);
  }

  return return_value;
}

//插入新类别
void CategoryView::insert_category()
{

}

void CategoryView::edit_category()
{
	if (!editstatus)
	{
		std::cout << "Test edit_category function." << std::endl;
		Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
		if(refSelection)
		{
			Gtk::TreeModel::iterator iter = refSelection->get_selected();
			if(iter)
			{
				Gtk::ListStore::Path path=refTreeModel->get_path(iter);
				Gtk::TreeViewColumn* column=(get_column(0));
				cellrenderer.property_editable()=true;
				editstatus=true;
				set_cursor(path,*column,true);
			}
		}
	}
}

//删除一个分类，对应分类下的所有文档信息也将删除，弹出对话框请用户确认
void CategoryView::remove_category()
{

}

//删除所有分类
void CategoryView::remove_all_category()
{
	Gtk::MessageDialog dialog("Are you sure to delete all themes?", false, Gtk::MESSAGE_QUESTION,Gtk::BUTTONS_OK_CANCEL,true);
	int result=dialog.run();
	if (result==Gtk::RESPONSE_OK )
	{
		sdms::category c;
		mydoc->del(&c);
		refTreeModel->clear();
	}		
}

void CategoryView::category_movemode()
{
	std::vector<Gtk::TargetEntry> targets;
	//std::cout<<"movemode"<<std::endl;	
	drag_dest_unset();
	drag_source_unset();
	if (menuCategoryMoveMode.get_active()) 
	{
		targets.push_back( Gtk::TargetEntry("GTK_TREE_MODEL_ROW") );
		c1.disconnect();
		c2=signal_drag_end().connect( sigc::mem_fun(*this, &CategoryView::drag_end) );
	}else{
		unset_rows_drag_source ();
		//std::cout<<"test"<<std::endl;
		targets.push_back( Gtk::TargetEntry("CATEGORY-ID") );
		c2.disconnect();
		c1=signal_drag_data_get().connect(sigc::mem_fun(*this,&CategoryView::drag_data_get));
	}	
	drag_source_set(targets);
	enable_model_drag_source(targets);
	targets.push_back( Gtk::TargetEntry("DOCUMENT-ID") );
	drag_dest_set(targets);		
	enable_model_drag_dest(targets,Gdk::ACTION_MOVE); 		
}

void CategoryView::datarender(Gtk::CellRenderer* /* renderer */, const Gtk::TreeModel::iterator& iter)
{
	//Get the value from the model and show it appropriately in the view:
	if(iter)
	{
		Gtk::TreeModel::Row row = *iter;
		cellrenderer.property_text() = row[columns.name];
	}
}

//保存当前编辑的分类
void CategoryView::save_category(const Glib::ustring& path_string, const Glib::ustring& new_text)
{

}

//更新treemodel的数据到数据库
void CategoryView::sync(Gtk::TreeModel::Children child)
{

}

void CategoryView::drag_end(const Glib::RefPtr<Gdk::DragContext>& context)
{
	//同步数据到数据库，包括排序，父子关系
	//首先要处理拖拽后的parent_id
	sync(refTreeModel->children());
	//update();
}
void CategoryView::drag_data_received(
        const Glib::RefPtr<Gdk::DragContext>& context, int x, int y,
        const Gtk::SelectionData& selection_data, guint, guint time)
{
	if (selection_data.get_data_type()=="DOCUMENT-ID")//接收docview的DND信息
	{
		//std::cout<<selection_data.get_data_type()<<std::endl;
		std::string sel=selection_data.get_data_as_string();
		Gtk::TreeModel::Path path;
		Gtk::TreeViewDropPosition 	 pos;
		get_dest_row_at_pos(x,y,path,pos);
		Gtk::TreeModel::iterator  iter = refTreeModel->get_iter(path);
		std::vector<std::string> singledoc=utils::explode(sel,",");
		sdms::category t;
		//t.name=(*iter)[columns.name];
		for (int i=0;i<singledoc.size();i++)
		{
			sdms::document d;
			//d.id=utils::fromString<int>(singledoc[i]);
			//更新成功后再更新count，避免中间的插入错误
			//if (mydoc->update(&t,&d))  (*iter)[columns.count]=t.count;
		}
	}
	//Gtk::TreeView::drag_data_received(context,int,int,selection_data,guint,time);
	//context->drag_finish(false, false, time);
}
void CategoryView::drag_data_get(const Glib::RefPtr<Gdk::DragContext>&,   Gtk::SelectionData& selection_data, guint, guint)
{
	std::string id;		
	Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
	if(refSelection)
	{
		std::list<Gtk::TreeModel::Path> selected = refSelection->get_selected_rows();
	 //默认的多选拖动行为不够友好
	 //是否需要自己进一步处理？
	 	//std::cout<<selected.size()<<std::endl;
	 	for(std::list<Gtk::TreeModel::Path>::iterator i=selected.begin();i!=selected.end();i++)
		{
			Gtk::TreeModel::iterator iter = refTreeModel->get_iter(*i);
			Gtk::TreeModel::Row row = *iter;
			if (i!=selected.begin()) id+=",";
			//id+=row[columns.name];
		}
	}
	selection_data.set(selection_data.get_target(), 8 /* 8 bits format */,
         (const guchar*)id.c_str(),id.size());			
}

void CategoryView::select_category(const Gtk::TreeStore::Path& path, Gtk::TreeViewColumn* column)
{
	Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
	if(refSelection)
	{
		Gtk::TreeModel::iterator iter = refSelection->get_selected();
		if(iter && filterview)
		{
			sdms::categoryfilter tf;
			tf.set_documents(mydoc);
			//tf.set_id((*iter)[columns.id]);
			tf.eval();
			 Glib::ustring name=(*iter)[columns.name];
			 tf.set_name(name);
			 filterview->clear();
			 filterview->add(tf);
			//docview->update(&tf);
		}
	}
}
 void CategoryView::set_docview(DocView* dv)
{
	docview=dv;
}
void CategoryView::set_filterview(FilterView* fv)
{
	filterview=fv;
}
void CategoryView::on_menu_file_popup_generic()
{
  std::cout << "A popup menu item was selected." << std::endl;

  Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection();
  if(refSelection)
  {
    Gtk::TreeModel::iterator iter = refSelection->get_selected();
    if(iter)
    {
      std::cout << "  Selected publisher: " << (*iter)[columns.name] << std::endl;
    }
  }
}
 
